home *** CD-ROM | disk | FTP | other *** search
/ MacFormat 1995 January / macformat-020.iso / Shareware City / Developers / mega src / Source / yesno.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-06-01  |  6.4 KB  |  271 lines  |  [TEXT/KAHL]

  1. /* ========== the commmand file: ==========
  2.  
  3.     yesno.c
  4.     
  5.     Copyright (c) 1993,1994 Newport Software Development
  6.     
  7.     You may distribute unmodified copies of this file for
  8.     noncommercial purposes.  You may use this file as a
  9.     reference when writing your own nShell(tm) commands.
  10.     
  11.     All other rights are reserved.
  12.     
  13.    ========== the commmand file: ========== */
  14.  
  15. #include "nshc.h"
  16. #include "str_utl.proto.h"
  17. #include "nshc_utl.proto.h"
  18.  
  19. /* ======================================== */
  20.  
  21. // our data record, NewHandled and attached to nshc_parms->data
  22.  
  23. typedef struct {
  24.  
  25.     Str255    theString;        // theString we are receiving fromthe keyboard
  26.     int        overrun;        // non-zero if theString has exceeded 255 chars
  27.     int        stdin;            // non-zero if we input from stdin
  28.  
  29. } t_yesno_data;
  30.  
  31. typedef t_yesno_data **t_yesno_handle;
  32.  
  33. /* ======================================== */
  34.  
  35. // prototypes - for local use only
  36.  
  37. void yesno_by_parameters( t_nshc_parms *nshc_parms, t_nshc_calls *nshc_calls );
  38. void yesno_collect( t_nshc_parms *nshc_parms, t_nshc_calls *nshc_calls );
  39. void yesno_continue( t_nshc_parms *nshc_parms, t_nshc_calls *nshc_calls );
  40. void yesno_getchar( t_nshc_parms *nshc_parms, t_nshc_calls *nshc_calls );
  41. void yesno_print( t_nshc_parms *nshc_parms, t_nshc_calls *nshc_calls );
  42. void yesno_start( t_nshc_parms *nshc_parms, t_nshc_calls *nshc_calls );
  43. void yesno_stop( t_nshc_parms *nshc_parms );
  44.  
  45. /* ======================================== */
  46.  
  47. // if the user put his text on the command line, do it all in one operation
  48.  
  49. void yesno_print( t_nshc_parms *nshc_parms, t_nshc_calls *nshc_calls )
  50. {
  51.     int                size;
  52.     int                lastchar;
  53.     t_yesno_handle    ndata;
  54.     
  55.     ndata = (t_yesno_handle)(nshc_parms->data);
  56.         
  57.     HLock( ndata );
  58.     
  59.     size = (**ndata).theString[0];
  60.     
  61.     if (size) {
  62.         nshc_calls->NSH_putStr( (**ndata).theString );
  63.         lastchar = (**ndata).theString[size];
  64.         if ((lastchar == '\r') || (lastchar == ' '))
  65.             nshc_calls->NSH_puts("(y/n): ");
  66.         else
  67.             nshc_calls->NSH_puts(" (y/n): ");
  68.         }
  69.     else
  70.         nshc_calls->NSH_puts("(y/n): ");
  71.         
  72.     HUnlock( ndata );
  73. }
  74.  
  75. /* ======================================== */
  76.  
  77. // if the user put his text on the command line, do it all in one operation
  78.  
  79. void yesno_by_parameters( t_nshc_parms *nshc_parms, t_nshc_calls *nshc_calls )
  80. {
  81.     int                arg;
  82.     int                got_one;
  83.     int                length;
  84.     char            *p;
  85.     Str255            localString;
  86.     t_yesno_handle    ndata;
  87.     
  88.     nshc_parms->result = NSHC_NO_ERR;
  89.     nshc_parms->action = nsh_continue;
  90.             
  91.     ndata = (t_yesno_handle)(nshc_parms->data);
  92.             
  93.     arg = 1;
  94.     got_one = 0;
  95.     length = 0;
  96.     localString[0] = 0;
  97.     
  98.     while ( arg < nshc_parms->argc ) {
  99.         if ( nshc_is_operand( nshc_parms, arg) ) {
  100.             p = &nshc_parms->arg_buf[nshc_parms->argv[arg]];
  101.             length += cStrLen(p);
  102.             if (length < 255) {
  103.                 if (got_one)
  104.                     localString[++localString[0]] = ' ';
  105.                 pStrAppendC( localString, p );
  106.                 }
  107.             got_one = 1;
  108.             }
  109.         arg++;
  110.         }
  111.         
  112.     if (length > 255) {
  113.             nshc_calls->NSH_putStr_err("\pyesno: stdin exceeds 255 chars.\r");
  114.             nshc_parms->result = NSHC_ERR_GENERAL;
  115.             nshc_parms->action = nsh_stop;
  116.             }
  117.         else
  118.             if (length) {
  119.                 HLock( ndata );
  120.                 pStrCopy( (**ndata).theString, localString );
  121.                 HUnlock( ndata );
  122.                 yesno_print( nshc_parms, nshc_calls );
  123.                 }
  124.             else
  125.                 nshc_calls->NSH_puts("(y/n): ");
  126.         
  127. }
  128.  
  129. /* ======================================== */
  130.  
  131. // this _continue routine is used to pick up input from stdin, it loops until
  132. // an end-of-input is found. It posts the input text if it does not exceed 255
  133. // characters, otherwise it posts an error message.  If input exceeds 255 chars,
  134. // all extra chars are eaten.
  135.  
  136. void yesno_collect( t_nshc_parms *nshc_parms, t_nshc_calls *nshc_calls )
  137. {
  138.     int        value;
  139.     int        size;
  140.     Str255    localString;
  141.     
  142.     t_yesno_handle    ndata;
  143.     
  144.     ndata = (t_yesno_handle)(nshc_parms->data);
  145.         
  146.     HLock( ndata );
  147.     
  148.     value = nshc_calls->NSH_getStr( localString );
  149.     
  150.     if (value) {
  151.         size = localString[0] + (**ndata).theString[0];
  152.         if (size > 255) (**ndata).overrun = 1;
  153.         if (!(**ndata).overrun) pStrAppend( (**ndata).theString, localString );
  154.         }
  155.         
  156.     HUnlock( ndata );
  157.         
  158.     if (value == -1) {
  159.     
  160.         if ((**ndata).overrun) {
  161.             nshc_calls->NSH_putStr_err("\pyesno: stdin exceeds 255 chars.\r");
  162.             nshc_parms->result = NSHC_ERR_GENERAL;
  163.             }
  164.         else {
  165.             yesno_print( nshc_parms, nshc_calls );
  166.             nshc_parms->result = NSHC_NO_ERR;
  167.             }
  168.             
  169.         (**ndata).stdin = 0;    
  170.         }
  171. }
  172.  
  173. /* ======================================== */
  174.  
  175. void yesno_getchar( t_nshc_parms *nshc_parms, t_nshc_calls *nshc_calls )
  176. {
  177.     int        answer = -1;
  178.         
  179.     switch ( nshc_calls->NSH_getchar() ) {
  180.         case 'y':
  181.         case 'Y':                                    // affirmative
  182.             answer = 0;
  183.             break;
  184.         case 'n':
  185.         case 'N':                                    // negative
  186.             answer = 1;
  187.             break;
  188.         case '\0':                                    // null when no keys pressed
  189.             break;
  190.         default:
  191.             nshc_calls->NSH_putchar('\r');
  192.             yesno_print( nshc_parms, nshc_calls ); // huh?
  193.             break;
  194.         }
  195.  
  196.     if (answer >= 0) {
  197.         nshc_calls->NSH_putchar('\r');
  198.         nshc_parms->result = answer;
  199.         nshc_parms->action = nsh_stop;
  200.         }
  201. }
  202.  
  203. /* ======================================== */
  204.  
  205. // state machine start
  206.  
  207. void yesno_start( t_nshc_parms *nshc_parms, t_nshc_calls *nshc_calls )
  208. {
  209.     t_yesno_handle    ourData;
  210.  
  211.     ourData = (t_yesno_handle)NewHandle( sizeof(t_yesno_data) );
  212.  
  213.     if (ourData) {
  214.         (**ourData).theString[0] = 0;
  215.         (**ourData).overrun = 0;
  216.         (**ourData).stdin = nshc_got_option( nshc_parms, 'i' );
  217.         nshc_parms->data = (Handle)ourData;
  218.         nshc_parms->action = nsh_continue;
  219.         if (!(**ourData).stdin)
  220.             yesno_by_parameters( nshc_parms, nshc_calls );
  221.         }
  222.     else {
  223.         nshc_calls->NSH_putStr_err("\pyesno: Could not allocate storage.\r");
  224.         nshc_parms->result = NSHC_ERR_MEMORY;
  225.         nshc_parms->action = nsh_idle;
  226.         }
  227. }
  228.  
  229. /* ======================================== */
  230.  
  231. // state machine continue
  232.  
  233. void yesno_continue( t_nshc_parms *nshc_parms, t_nshc_calls *nshc_calls )
  234. {
  235.     if ((**(t_yesno_handle)(nshc_parms->data)).stdin)
  236.         yesno_collect(nshc_parms,nshc_calls);
  237.     else
  238.         yesno_getchar(nshc_parms,nshc_calls);
  239. }
  240.  
  241. /* ======================================== */
  242.  
  243. // state machine stop
  244.  
  245. void yesno_stop( t_nshc_parms *nshc_parms )
  246. {        
  247.     if (nshc_parms->data)
  248.         DisposeHandle(nshc_parms->data);
  249.  
  250.     nshc_parms->action = nsh_idle;
  251. }
  252.  
  253. /* ======================================== */
  254.  
  255. void main(t_nshc_parms *nshc_parms, t_nshc_calls *nshc_calls)
  256. {
  257.     if (nshc_bad_version( nshc_parms, nshc_calls, NSHC_VERSION )) return;
  258.         
  259.     switch (nshc_parms->action) {
  260.         case nsh_start:
  261.             yesno_start(nshc_parms,nshc_calls);
  262.             break;
  263.         case nsh_continue:
  264.             yesno_continue(nshc_parms,nshc_calls);
  265.             break;
  266.         default:
  267.             yesno_stop(nshc_parms);
  268.             break;
  269.         }
  270. }
  271.